package org.su.generalmvc.core;

import org.su.generalmvc.jdbc.DaoFactory;
import org.su.generalmvc.jdbc.IDao;
import org.su.generalmvc.annotaion.Transaction;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.SQLException;

/**
 * 管理控制器的初始和销毁方法,也是他们的生命周期
 * 
 * @author yangchuan
 * @version 1.0
 * @since 2012-03-06
 * 
 */
public class LifeCycle {

	Object controller;
	Method initMethod;
	int initTransLevel = -1;
	Method destroyMethod;
	int destroyTransLevel = -1;

	protected static final Log logger = LogFactory.getLog(LifeCycle.class);

	public LifeCycle(Object controller) {
		this.controller = controller;
	}

	public void setInitMethod(Method method) {
		this.initMethod = method;
		initTransLevel = getTransLevel(method);
	}

	private int getTransLevel(Method method) {
		int transLevel = -1;
		// 确定事物级别
		Class<?>[] parameterTypes = method.getParameterTypes();
		if (parameterTypes.length > 0) {
			transLevel = 0;
			Transaction transaction = method.getAnnotation(Transaction.class);
			if (null != transaction) {
				transLevel = transaction.value();
			}
		}

		return transLevel;
	}

	public void setDestroyMethod(Method method) {
		this.destroyMethod = method;
		destroyTransLevel = getTransLevel(method);
	}

	public void init() throws ServiceException {
		if (initMethod != null) {
			try {
				invoke(controller, initMethod, initTransLevel);
				logger.debug(" controler init:"
						+ controller.getClass().getName());
			} catch (Exception e) {
				throw new ServiceException(e);
			}
		}
	}

	public static void invoke(Object controller, Method method, int transLevel)
			throws SQLException, IllegalAccessException,
            InvocationTargetException {
		if (transLevel >= 0) {
			IDao dao = DaoFactory.createDao(transLevel);
			boolean commit = false;
			try {
				method.invoke(controller, dao);
				commit = true;
			} finally {
				try {
					dao.endTrans(commit);
				} finally {
					DaoFactory.forceCloseDao(dao);
				}
			}
		} else {
			method.invoke(controller);
		}
	}

	public void destroy() {
		if (destroyMethod != null) {
			try {
				invoke(controller, destroyMethod, destroyTransLevel);
				logger.debug(" controler destroy:"
						+ controller.getClass().getName());
			} catch (Exception e) {
				// 结束只打印，不影响其他对象的释放操作
				logger.error(" controler destroy exception:"
						+ controller.getClass().getName(), e);
			}
		}
	}
}
